package com.zzw.utils;

import cn.hutool.extra.qrcode.QrCodeUtil;
import cn.hutool.extra.qrcode.QrConfig;
import lombok.extern.slf4j.Slf4j;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;


/*
代码解释：
    二维码生成：
        QrConfig配置对象设置二维码的尺寸为400x400像素，并指定了前景色为黑色，背景色为白色。
        使用Hutool的QrCodeUtil.generate方法生成不带Logo的二维码。
    文本添加：
        如果传入的productName不为空，则创建一个新的BufferedImage对象，其高度比原二维码增加TEXT_AREA_HEIGHT像素，用于显示产品名称。
        使用Graphics2D对象在新图像上绘制二维码和文本。文本将居中显示在二维码的下方。
    图像输出：
        如果指定了qrCodePath路径，则将生成的二维码图像保存到该路径下的文件中。
        无论是否指定路径，该方法都会返回一个BufferedImage对象，以支持内存中批量处理的需求。

使用方法：
在需要生成二维码的地方，调用此方法并获取BufferedImage对象，然后可以将这些图像批量保存到磁盘，或者进一步处理，例如压缩和上传。

BufferedImage qrCodeImage = ZXingCodeHutool.getLogoQRCode(qrCodeUrl, "NO:" + equipmentNumber, null);

通过这种方式，二维码生成过程中的I/O操作得到了有效控制，性能得以提升。
 */
@Slf4j
public class ZXingCodeHutool {

    private static final int QR_CODE_SIZE = 400;
    private static final int IMAGE_PADDING = 20;
    private static final int FONT_SIZE = 30;
    private static final int TEXT_AREA_HEIGHT = 20;

    /**
     * 生成带Logo的二维码，并返回BufferedImage对象
     *
     * @param qrCodeUrl    二维码内容（URL）
     * @param productName  产品名称（会显示在二维码下方）
     * @param qrCodePath   （可选）输出二维码图片路径，如果为null，则仅返回BufferedImage对象
     * @return BufferedImage 生成的二维码图像对象
     */
    //public static BufferedImage getLogoQRCode(String qrCodeUrl, String productName, String qrCodePath) {
    //    // 创建二维码配置，设置二维码图片的宽度和高度为400像素
    //    QrConfig config = new QrConfig(QR_CODE_SIZE, QR_CODE_SIZE);
    //
    //    config.setForeColor(Color.BLACK.getRGB()); // 设置前景色为黑色
    //    config.setBackColor(Color.WHITE.getRGB()); // 设置背景色为白色
    //
    //    // 生成不带Logo的二维码图片
    //    BufferedImage qrCodeImage = QrCodeUtil.generate(qrCodeUrl, config);
    //
    //    // 如果需要在二维码下方添加产品名称
    //    if (productName != null && !productName.isEmpty()) {
    //        // 创建一个新的BufferedImage对象，用于在二维码下方添加产品名称
    //        BufferedImage outImage = new BufferedImage(QR_CODE_SIZE, QR_CODE_SIZE + TEXT_AREA_HEIGHT, BufferedImage.TYPE_INT_RGB);
    //        Graphics2D g2 = outImage.createGraphics();
    //
    //        // 填充背景色为白色
    //        g2.setColor(Color.WHITE);
    //        g2.fillRect(0, 0, QR_CODE_SIZE, QR_CODE_SIZE + TEXT_AREA_HEIGHT);
    //
    //        // 将生成的二维码图片绘制到新的BufferedImage对象中
    //        g2.drawImage(qrCodeImage, 0, 0, QR_CODE_SIZE, QR_CODE_SIZE, null);
    //
    //        // 设置字体和颜色
    //        g2.setColor(Color.BLACK);
    //        g2.setFont(new Font("宋体", Font.BOLD, FONT_SIZE));
    //
    //        // 计算产品名称的宽度，以便居中显示
    //        int strWidth = g2.getFontMetrics().stringWidth(productName);
    //
    //        // 绘制产品名称文本，使其位于二维码的下方
    //        //int xPosition = (QR_CODE_SIZE - strWidth) / 2;
    //        //int yPosition = QR_CODE_SIZE + (TEXT_AREA_HEIGHT + FONT_SIZE) / 2 - IMAGE_PADDING - 10;
    //        //g2.drawString(productName, xPosition, yPosition);  // 这里将y坐标改为405，缩小与二维码的间距
    //        g2.drawString(productName, 200 - strWidth / 2, 405);  // 这里将y坐标改为405，缩小与二维码的间距
    //
    //
    //        // 释放Graphics2D对象
    //        g2.dispose();
    //
    //        // 将新的BufferedImage对象赋值给qrCodeImage
    //        qrCodeImage = outImage;
    //    }
    //
    //    // 如果指定了路径，则将图像写入文件
    //    if (qrCodePath != null) {
    //        try {
    //            ImageIO.write(qrCodeImage, "jpg", new File(qrCodePath));
    //        } catch (IOException e) {
    //            e.printStackTrace();
    //        }
    //    }
    //
    //    return qrCodeImage; // 返回生成的二维码图像
    //}



    /**
     * 生成带Logo的二维码，并返回byteArrayInputStream对象
     *
     * @param qrCodeUrl    二维码内容（URL）
     * @param productName  产品名称（会显示在二维码下方）
     * @return byteArrayInputStream 二维码图像的字节输入流，需在使用后关闭
     */
    public static ByteArrayInputStream getLogoQRCode(String qrCodeUrl, String productName) {
        // 创建二维码配置，设置二维码图片的宽度和高度为400像素
        QrConfig config = new QrConfig(QR_CODE_SIZE, QR_CODE_SIZE);

        config.setForeColor(Color.BLACK.getRGB()); // 设置前景色为黑色
        config.setBackColor(Color.WHITE.getRGB()); // 设置背景色为白色

        // 生成不带Logo的二维码图片
        BufferedImage qrCodeImage = QrCodeUtil.generate(qrCodeUrl, config);

        // 如果需要在二维码下方添加产品名称
        if (productName != null && !productName.isEmpty()) {
            // 创建一个新的BufferedImage对象，用于在二维码下方添加产品名称
            BufferedImage outImage = new BufferedImage(QR_CODE_SIZE, QR_CODE_SIZE + TEXT_AREA_HEIGHT, BufferedImage.TYPE_INT_RGB);
            Graphics2D g2 = outImage.createGraphics();

            // 填充背景色为白色
            g2.setColor(Color.WHITE);
            g2.fillRect(0, 0, QR_CODE_SIZE, QR_CODE_SIZE + TEXT_AREA_HEIGHT);

            // 将生成的二维码图片绘制到新的BufferedImage对象中
            g2.drawImage(qrCodeImage, 0, 0, QR_CODE_SIZE, QR_CODE_SIZE, null);

            // 设置字体和颜色
            g2.setColor(Color.BLACK);
            g2.setFont(new Font("宋体", Font.BOLD, FONT_SIZE));

            // 计算产品名称的宽度，以便居中显示
            int strWidth = g2.getFontMetrics().stringWidth(productName);

            // 绘制产品名称文本，使其位于二维码的下方
            //int xPosition = (QR_CODE_SIZE - strWidth) / 2;
            //int yPosition = QR_CODE_SIZE + (TEXT_AREA_HEIGHT + FONT_SIZE) / 2 - IMAGE_PADDING - 10;
            //g2.drawString(productName, xPosition, yPosition);  // 这里将y坐标改为405，缩小与二维码的间距
            g2.drawString(productName, 200 - strWidth / 2, 405);  // 这里将y坐标改为405，缩小与二维码的间距


            // 释放Graphics2D对象
            g2.dispose();

            // 将新的BufferedImage对象赋值给qrCodeImage
            qrCodeImage = outImage;
        }

        try {
            //将BufferedImage转为字节输入流
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            ImageIO.write(qrCodeImage, "jpg", byteArrayOutputStream);
            qrCodeImage.flush();//清空缓存
            qrCodeImage = null;//释放内存
            //转换为输入流
            return new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
        } catch (IOException e) {
            log.error("二维码转换为流失败", e);
            throw new RuntimeException("二维码生成失败", e); // 抛出自定义异常，便于上层处理
        }
    }
}
